#ifndef _THREAD_H_
#define _THREAD_H_
 
#include <iostream>
#include <string>
#include <pthread.h>   // POSIX线程库头文件
#include <cstdio>
#include <cstring>
#include <functional>  // 用于std::function函数对象
 
namespace ThreadModlue{
    static uint32_t number = 1;
 
    // 线程类封装，封装了POSIX线程的常用操作
    class Thread{
        // 定义函数对象类型，作为线程执行的任务函数
        using func_t = std::function<void()>;
    private:
        // 私有成员函数：设置线程为运行状态
        void EnableRunning() { _isrunning = true;}
        // 私有成员函数：设置线程为分离状态
        void EnableDetach() { _isdetach = true;}
        
        // 线程入口函数（必须为静态函数，符合pthread_create要求） --- 否则有隐藏的this*的干扰
        // 参数为当前Thread对象指针，通过它调用成员函数
        static void* Routine(void* args) {
            // 将void*参数转换为Thread*类型
            Thread* self = static_cast<Thread*>(args); // 通过这个，我们就可以间接拿到普通成员变量了
            // 标记线程开始运行
            self->EnableRunning();
            // 如果线程需要分离，执行分离操作
            if(self->_isdetach) {
                self->Detach();
            }
            // 设置线程名称
            pthread_setname_np(self->_tid, self->_name.c_str());
            // 执行用户传入的任务函数
            self->_func();
            return nullptr;
        }
    public:
        // 构造函数：接收一个任务函数作为参数
        Thread(func_t func)
        :_tid(0),                  // 线程ID初始化为0
         _isdetach(false),         // 初始为非分离状态
         _isrunning(false),        // 初始为未运行状态
         _res(nullptr),            // 线程返回值初始化为空
         _func(func)               // 绑定用户传入的任务函数
        {
            // 自动生成线程名称（格式：thread[编号]）
            _name = "thread[" + std::to_string(number++) + "]";
        }
 
        // 启动线程：创建并执行线程
        bool Start(){
            // 如果线程已在运行，直接返回失败
            if(_isrunning) return false;
            // 调用pthread_create创建线程
            // 参数：线程ID指针、线程属性（默认）、入口函数、当前对象指针
            int n = pthread_create(&_tid, nullptr, Routine, this);
            if(n != 0) {  // 创建失败
                std::cerr << "create thread error!" << std::endl;
                return false;
            }
            std::cout << _name << " -- create thread success" << std::endl;
            return true;
        }
 
        // 停止线程：通过取消线程执行来终止线程
        bool Stop() {
            // 如果线程未运行，直接返回失败
            if(!_isrunning) return false;
            // 调用pthread_cancel取消线程
            int n = pthread_cancel(_tid);
            if(n != 0) {  // 取消失败
                std::cerr << "stop thread error!" << std::endl;
                return false;
            }
            // 标记线程为非运行状态
            _isrunning = false;
            std::cout << _name << " -- stop thread success" << std::endl;
            return true;
        }
 
        // 线程join操作：等待线程结束并回收资源
        void Join() {
            // 如果线程已分离，无需join，直接返回
            if(_isdetach) {
                std::cout << "该线程已经和主线程分离，无需 jion ！" << std::endl;
                return;
            }
            // 调用pthread_join等待线程结束
            int n = pthread_join(_tid, &_res);
            if(n != 0) {  // join失败
                std::cerr << "join thread error! --- strerror: " << strerror(n) <<  std::endl;
                return;
            }
            std::cout << "join thread success" << std::endl;
        }
 
        // 线程detach操作：将线程设置为分离状态，自动回收资源
        void Detach() {
            // 如果已分离或未运行，直接返回
            if(_isdetach || !_isrunning) return;
            if(_isrunning) {
                // 调用pthread_detach设置分离状态
                pthread_detach(_tid);
                // 标记线程为分离状态
                EnableDetach();
            }
        }

        const std::string& Name() const { return _name; }
 
        // 析构函数：此处为空实现（线程资源通过join或detach管理）
        ~Thread(){}
        
    private:
        pthread_t _tid;         // 线程ID
        std::string _name;      // 线程名称
        bool _isdetach;         // 线程是否为分离状态
        bool _isrunning;        // 线程是否正在运行
        void* _res;             // 线程执行结果（返回值）
        func_t _func;           // 线程需要执行的任务函数
    };
}
 
#endif